#ifndef	WF_LOWFREPROTE_GLOBALS
#define	WF_LOWFREPROTE_GLOBALS
#include <includes.h>
#include "WF_LowFreProte.h"

static uint8_t ShutDownAlarm_WorkStepHandle(uint8_t *TempWFStep,uint8_t *TempWFPeriod,uint8_t *WFStaChange,uint8_t Solution)
{
  if(GetFlagShareBufferDataContent(NULL,CfgOperaType_None,FlagShareBuffer_GenWorkingSta,GenWorkStaOrd_AlarmShutDown))//检查控制器的运行状态是否在停机告警态
  {
  	if(Solution&GenFaultWay_Action)
    {
        SetNewWorkFlowStepStatus(TempWFStep,TempWFPeriod,WFStaChange,LowFreProteStep_endStep);
        return(DEF_TRUE);
    }
  }
  
  return(DEF_FALSE);
}

uint8_t LowFreProteStep_1st(uint8_t TempWorkflow,uint8_t TempWFStep,uint8_t TempWFPeriod, uint8_t *TempOutAlarm)
{
    uint8_t ActInform = DEF_FALSE,WFStaChange = DEF_FALSE;
    /* 未完成波动率测试 */
    if((FlowDataStatus & (1<<WorkflowMode_Volatility))==0)
    {
        SetNewWorkflowModeStatus(&TempWorkflow,&TempWFStep,&TempWFPeriod,&WFStaChange,WorkflowMode_Ending);
        UpdateWorkflowModeStatus(&TempWorkflow, &TempWFStep,&TempWFPeriod, &WFStaChange);
        return (ActInform);
    }

    CurrProcCountdownEnable = DEF_TRUE;
    SetNextNewWorkFlowStepStatus(&TempWFStep,&TempWFPeriod,&WFStaChange,LowFreProteStep_Maximum);
    /* Update Workflow--Step and Mode */
    UpdateWorkflowModeStatus(&TempWorkflow, &TempWFStep,&TempWFPeriod, &WFStaChange);
    return (ActInform);
}
/**
 * @brief 合闸前检查
 * 
 * @param TempWorkflow 
 * @param TempWFStep 
 * @param TempWFPeriod 
 * @param TempOutAlarm 
 * @return uint8_t 
 */
uint8_t LowFreProteStep_2st(uint8_t TempWorkflow,uint8_t TempWFStep,uint8_t TempWFPeriod, uint8_t *TempOutAlarm)
{
    uint8_t ActInform = DEF_FALSE,WFStaChange = DEF_FALSE;
    ActInform |= SwitchBefCheckStep(TempWorkflow,TempWFStep,TempWFPeriod,LowFreProteStep_Maximum,
        share_parameterCfgData_st.underFreqCfg_st.EngineInitStart_time,share_parameterCfgData_st.underFreqCfg_st.EngineInitSpeed,ShutDownAlarm_WorkStepHandle);
    return (ActInform);
}
uint8_t LowFreProteStep_3st(uint8_t TempWorkflow,uint8_t TempWFStep,uint8_t TempWFPeriod, uint8_t *TempOutAlarm)
{
    uint8_t ActInform = DEF_FALSE,WFStaChange = DEF_FALSE;
    /* AlarmShutDown     */
    if(ShutDownAlarm_WorkStepHandle(&TempWFStep,&TempWFPeriod,&WFStaChange,GenFaultWay_ALL))
    {
        UpdateWorkflowModeStatus(&TempWorkflow, &TempWFStep,&TempWFPeriod, &WFStaChange);
        return (ActInform);
    }
    switch (TempWFPeriod)
    {
    case WorkflowPeriod_Entry:
        share_UnderFreqData_st.baseData_st.SteadyVoltage_U = share_VolatilityData_st.baseData_st.SteadyVoltage_U;
        share_UnderFreqData_st.baseData_st.SteadyVoltage_V = share_VolatilityData_st.baseData_st.SteadyVoltage_V;
        share_UnderFreqData_st.baseData_st.SteadyVoltage_W = share_VolatilityData_st.baseData_st.SteadyVoltage_W;
        share_UnderFreqData_st.baseData_st.SteadyAverageVolt = share_VolatilityData_st.baseData_st.SteadyAverageVolt;
        SetNewWorkFlowPeriodStatus(&TempWFPeriod,&WFStaChange,WorkflowPeriod_1st);
        break;
    case WorkflowPeriod_1st:
        // 等待数据稳定
        SMTimerCounter = share_parameterCfgData_st.underFreqCfg_st.WaitVoltStab_time * WorkFlowTimingFreq;
        SetNewWorkFlowPeriodStatus(&TempWFPeriod,&WFStaChange,WorkflowPeriod_2nd);
        break;
    case WorkflowPeriod_2nd:
        if(SMTimerCounter==0)
        {
            SetNewWorkFlowPeriodStatus(&TempWFPeriod,&WFStaChange,WorkflowPeriod_3nd);
        }
        break;
    case WorkflowPeriod_3nd:
        ModifyFlagShareBufferDataContent(NULL, CfgOperaType_None, FlagShareBuffer_WFWave, WFWave_Waveform,BitOperaOpt_Set);
        ActInform |= WorkflowOutRequestBit_WaveRequest;
        SetNewWorkFlowPeriodStatus(&TempWFPeriod,&WFStaChange,WorkflowPeriod_4nd);
        break;
    case WorkflowPeriod_4nd:    
        // 停留方便观察前段数据
        SMTimerCounter = 1 * WorkFlowTimingFreq;
        SetNewWorkFlowPeriodStatus(&TempWFPeriod,&WFStaChange,WorkflowPeriod_5nd);
        break;
    case WorkflowPeriod_5nd:    
        if(SMTimerCounter==0)
        {
            SetNextNewWorkFlowStepStatus(&TempWFStep,&TempWFPeriod,&WFStaChange,LowFreProteStep_Maximum);
        }
        break;
    }
    /* Update Workflow--Step and Mode */
    UpdateWorkflowModeStatus(&TempWorkflow, &TempWFStep,&TempWFPeriod, &WFStaChange);
    return (ActInform);
}
/**
 * @brief 停机数据采集
 * 
 * @param TempWorkflow 
 * @param TempWFStep 
 * @param TempWFPeriod 
 * @param TempOutAlarm 
 * @return uint8_t 
 */
uint8_t LowFreProteStep_4st(uint8_t TempWorkflow,uint8_t TempWFStep,uint8_t TempWFPeriod, uint8_t *TempOutAlarm)
{
    uint8_t ActInform = DEF_FALSE,WFStaChange = DEF_FALSE;
    if(TempWFPeriod==WorkflowPeriod_Entry)
    {
        if(PidReqPriMoverStartStop(share_parameterCfgData_st.underFreqCfg_st.EngineShuntDownSpeed,share_parameterCfgData_st.underFreqCfg_st.EngineStop_time,
            PriMover_ENUM_Type_Stop,share_parameterCfgData_st.underFreqCfg_st.EngineStop_time+5,ShareInOrderSta_PriMoverStop))
        {
            ModifyFlagShareBufferDataContent(NULL, CfgOperaType_None, FlagShareBuffer_WFWave, WFWave_LowFreProte,BitOperaOpt_Set);
            ActInform |= WorkflowOutRequestBit_WaveRequest;
        }
    }
    else
    {
        /* AlarmShutDown     */
        if(ShutDownAlarm_WorkStepHandle(&TempWFStep,&TempWFPeriod,&WFStaChange,GenFaultWay_ALL))
        {
            UpdateWorkflowModeStatus(&TempWorkflow, &TempWFStep,&TempWFPeriod, &WFStaChange);
            return (ActInform);
        }
        if(GetShareBufferDataContent(App_Sem_WORKFLOW, CfgOperaType_OSSem, &ShareBuffer_SharePIDOrderSta[ShareInOrderSta_PriMoverStop])==PIDOrderSta_DEF_SUCCESS)
        {
            SetNextNewWorkFlowStepStatus(&TempWFStep,&TempWFPeriod,&WFStaChange,LowFreProteStep_endStep);
            ActInform |=WorkflowOutRequestBit_NextMode;
        }

    }
    /* Update Workflow--Step and Mode */
    UpdateWorkflowModeStatus(&TempWorkflow, &TempWFStep,&TempWFPeriod, &WFStaChange);
    return (ActInform);
}
uint8_t LowFreProteStep_end(uint8_t TempWorkflow,uint8_t TempWFStep,uint8_t TempWFPeriod, uint8_t *TempOutAlarm)
{
    uint8_t ActInform = DEF_FALSE,WFStaChange = DEF_FALSE;
    uint8_t WorkflowMode = TempWorkflow;
    if (TempWFPeriod == WorkflowPeriod_Entry)
    {
        SetNewWorkFlowPeriodStatus(&TempWFPeriod,&WFStaChange,WorkflowPeriod_1st);
        CurrProcCountdownEnable=DEF_FALSE;
        ModifyFlagShareBufferDataContent(NULL, CfgOperaType_None, FlagShareBuffer_WFWave, WFWave_WaveformEnd,BitOperaOpt_Set);
        ModifyFlagShareBufferDataContent(NULL, CfgOperaType_None, FlagShareBuffer_WFWave, WFWave_LowFreProteEnd,BitOperaOpt_Set);
        ActInform |= WorkflowOutRequestBit_WaveRequest;
    }
    else
    {
        FlowDataStatus |= (1<<WorkflowMode_LowFreProte);
        if(GetFlagShareBufferDataContent(NULL,CfgOperaType_None,FlagShareBuffer_GenWorkingSta,GenWorkStaOrd_AlarmShutDown))
        {
            SetNewWorkflowModeStatus(&TempWorkflow,&TempWFStep,&TempWFPeriod,&WFStaChange,WorkflowMode_StopPriMover);
        }
        else
        {
            //正常停机计算数据
            SetNewWorkflowModeStatus(&TempWorkflow,&TempWFStep,&TempWFPeriod,&WFStaChange,WorkflowMode_Ending);
            WaveSetFlowDataStatus(WorkflowMode);
        }
    }
    /* Update Workflow--Step and Mode */
    UpdateWorkflowModeStatus(&TempWorkflow, &TempWFStep,&TempWFPeriod, &WFStaChange);
    return (ActInform);
}

typedef uint8_t (*WorkFlowStepType)(uint8_t TempWorkflow,uint8_t TempWFStep,uint8_t TempWFPeriod, uint8_t *TempOutAlarm);
static const WorkFlowStepType LowFreProteStepTable[] = {
    (WorkFlowStepType)LowFreProteStep_1st        ,
    (WorkFlowStepType)LowFreProteStep_2st        ,
    (WorkFlowStepType)LowFreProteStep_3st        ,
    (WorkFlowStepType)LowFreProteStep_4st        ,
    (WorkFlowStepType)LowFreProteStep_end        ,
};


uint8_t WorkFlowHandling_LowFreProte(uint8_t TempWorkflow, uint8_t TempWFStep,uint8_t TempWFPeriod, uint8_t *TempOutAlarm)
{
    uint8_t ActInform = DEF_FALSE, WFStaChange = DEF_FALSE;

	ActInform |= (*LowFreProteStepTable[TempWFStep])(TempWorkflow,TempWFStep,TempWFPeriod, TempOutAlarm);

    /************************************/
    /* Update Workflow--Step and Mode */
    UpdateWorkflowModeStatus(&TempWorkflow, &TempWFStep,&TempWFPeriod, &WFStaChange);
    return (ActInform);
}
#endif